<template>
  <div
    ref="chart"
    style="height: 100%; width: 100%"
  ></div>
</template>
<script lang="ts">
import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
import * as echarts from 'echarts'

// import { Scatter3DChart } from 'echarts-gl'
// import { Grid3DComponent } from 'echarts-gl/lib/components'

// echarts.use([Scatter3DChart, Grid3DComponent])

@Component({
  name: 'templateChart',
})
export default class extends Vue {
  @Prop({ default: () => {} }) private option!: object
  chart: any = null
  @Watch('option', { deep: true })
  onOptionChange() {
    if (this.chart) {
      this.chart.dispose()
      this.chart = null
    }
    this.initChart()
  }

  __resizeHandler() {
    this.debounce(
      () => {
        if (this.chart) {
          this.chart.resize()
        }
      },
      100,
      false
    )
  }

  mounted() {
    require('echarts-gl')
    if (this.option) {
      this.initChart()
    }
    this.__resizeHandler()
    window.addEventListener('resize', this.__resizeHandler)
  }

  beforeDestroy() {
    if (!this.chart) {
      return
    }
    window.removeEventListener('resize', this.__resizeHandler)
    this.chart.dispose()
    this.chart = null
  }

  initChart() {
    this.chart = echarts.init(this.$refs.chart as HTMLDivElement, 'light') // default light dark三种颜色风格
    this.chart.setOption(this.option)
    this.__resizeHandler()
  }

  debounce(func: Function, wait: number, immediate: boolean) {
    let timeout: any, args: any, context: any, timestamp: any, result: any
    const that: any = this
    const later = function () {
      // 据上一次触发时间间隔
      const last = +new Date() - timestamp

      // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
      if (last < wait && last > 0) {
        timeout = setTimeout(later, wait - last)
      } else {
        timeout = null
        // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
        if (!immediate) {
          result = func.apply(context, args)
          if (!timeout) context = args = null
        }
      }
    }
    return function (...args: any): any {
      context = that
      timestamp = +new Date()
      const callNow = immediate && !timeout
      // 如果延时不存在，重新设定延时

      if (!timeout) timeout = setTimeout(later, wait)
      if (callNow) {
        result = func.apply(context, args)
        context = args = null
      }

      return result
    }
  }
}
</script>
